<template>
    <div class="materialContent">
        <div class="material-content-list">
            <div v-for="(item, index) in selectMaterials" :key="item.id || item.name" class="material-item">
                <div class="content">
                    <img :src="item.icon" alt="" />
                    <span>{{ item.name }}</span>
                </div>
                <el-icon v-if="!props.disabled && !(item.is_default_del === 1)" @click="del(index)">
                    <CircleCloseFilled />
                </el-icon>
            </div>
        </div>
        <div class="material-content-com">
            <el-popover
                v-if="materialTabs.length"
                popper-class="pop_select_box"
                :placement="placement"
                trigger="hover"
                :effect="!props.isHiddenLabel && selectMaterials.length < props.maxNum ? 'light' : 'dark'"
                :width="popoverWidth"
                :disabled="props.disabled">
                <template #reference>
                    <div class="upload_btn" :class="{ disabled: props.disabled }">
                        <el-icon><plus /></el-icon>
                        <span class="upload_text">{{ materialLabels }}</span>
                    </div>
                </template>
                <template #default>
                    <div v-if="!props.isHiddenLabel && selectMaterials.length < props.maxNum" class="upload_pop">
                        <div
                            v-for="tab in materialTabs"
                            :key="tab.type"
                            class="item_pop"
                            @click="openMatericalLib(tab)">
                            <img class="item_pop_icon" :src="tab.icon" alt="" />
                            <span class="item_pop_name">{{ tab.name }}</span>
                        </div>
                    </div>
                    <div v-else class="upload_default_pop">
                        <span>已达添加上限{{ props.maxNum }}个</span>
                    </div>
                </template>
            </el-popover>
        </div>
    </div>
    <ZWMatericalLib ref="ZWMatericalLibRef" @submit="getMaterlib" />
    <SelectAlreadyMaterial
        ref="selectAlreadyMaterialRef"
        v-model="selectAlreadyMaterialShow"
        @select="selectAlreadyMaterialFn" />
    <selectGroupAlreadyMaterial
        ref="selectGroupAlreadyMaterialRef"
        v-model="selectGroupAlreadyMaterialShow"
        @select="selectGroupAlreadyMaterialFn" />
</template>

<script setup lang="ts">
import { reactive, ref, computed, watch, onMounted, nextTick } from 'vue';
import { getSuffixIcon, getHashTabs, initAlreadyMaterialData } from '@/utils/utils';
import bus from '@/utils/bus';
import ZWMatericalLib from '@/components/channelNew/ZWMatericalLib.vue';
import SelectAlreadyMaterial from '@/components/zw/selectAlreadyMaterial/index.vue';
import selectGroupAlreadyMaterial from '@/components/zw/selectGroupAlreadyMaterial/index.vue';

const ZWMatericalLibRef = ref<HTMLElement>();
const selectAlreadyMaterialRef = ref<HTMLElement | null>();
const selectGroupAlreadyMaterialRef = ref<HTMLElement | null>();
const selectAlreadyMaterialShow = ref<boolean>(false);
const selectGroupAlreadyMaterialShow = ref<boolean>(false);

const welcomeFriendId = ref<string>(''); // 已有欢迎语id

interface Props {
    modelValue: string;
    disabled: boolean;
    maxNum: number;
    isHiddenLabel: boolean;
    reKey: string;
    singleList: Array<number>;
    tabs: Array<string>;
    materialData: Array<any>;
}

interface TabsType {
    icon: string;
    [propsName: string]: string | number;
}

const props = withDefaults(defineProps<Props>(), {
    modelValue: '',
    disabled: false,
    maxNum: 9,
    isHiddenLabel: false,
    reKey: '',
    singleList: () => [],
    tabs: () => ['1', '2', '3', '4', '5', '6'],
    materialData: () => []
});

const hashTabs = ref<Array<any>>([]);
const materialLabels = ref<string>('');
const materialTabs = ref<Array<TabsType>>([]);
const selectMaterials = ref<Array<TabsType>>([]);
const originMaterialIds = ref<Array<number>>([]);

const placement = computed(() => {
    return !props.isHiddenLabel && selectMaterials.value.length < props.maxNum ? 'bottom-start' : 'top';
});
const popoverWidth = computed(() => {
    const labelWidth = 36 + props.tabs.length * 44 + (props.tabs.length - 1) * 8;
    return !props.isHiddenLabel && selectMaterials.value.length < props.maxNum ? labelWidth : 150;
});

const getTabs = (): void => {
    const str = '';
    hashTabs.value = getHashTabs();
    if (props.tabs.length) {
        materialLabels.value = props.tabs.reduce((pre, tabKey, index, arr) => {
            return `${pre}${hashTabs.value[tabKey].name}${index < arr.length - 1 ? '/' : ''}`;
        }, str);
        materialTabs.value = props.tabs.map(tabKey => {
            return hashTabs.value[tabKey];
        });
    } else {
        materialLabels.value = str;
    }
};

const openMatericalLib = (tab: TabsType) => {
    ZWMatericalLibRef.value.showTabs = props.tabs.map(item => hashTabs.value[item].id);
    ZWMatericalLibRef.value.baseId = hashTabs.value[tab.type].id;
    ZWMatericalLibRef.value.maxNum = props.maxNum;
    if (tab.type == '15') {
        ZWMatericalLibRef.value.multiple = false;
    }
    ZWMatericalLibRef.value.selectInfoList.splice(0);
    ZWMatericalLibRef.value.selectInfoList.push(...getSelectInfoList());
    ZWMatericalLibRef.value.multiple = !props.singleList.includes(Number(tab.type));
    nextTick(() => {
        ZWMatericalLibRef.value.materVisible = true;
    });
};

const getSelectInfoList = () => {
    return selectMaterials.value.reduce((pre: any, cur: any): any[] => {
        const { type, id } = cur;
        const deleteItem = null;
        const userId = hashTabs.value[type].id;
        const isCheck = true;
        const flag = pre.some((item: any) => {
            if (item.type == type) {
                item.data.push({ ...cur, isCheck });
                return true;
            } else {
                return false;
            }
        });
        if (!flag) {
            const data = [{ ...cur, isCheck }];
            pre.push({ type, id: userId, deleteItem, data });
        }
        return [...pre];
    }, []);
};

const selectAlreadyMaterialFn = (data: any) => {
    const { content, welcome_friend_attachment, id } = data;
    welcomeFriendId.value = id;
    const defaultData = selectMaterials.value.filter(item => item.is_default_del === 1);
    const arr = [...defaultData, ...welcome_friend_attachment];
    arr.splice(props.maxNum);
    const res = initAlreadyMaterialData(arr);
    init(res, content);
};

const selectGroupAlreadyMaterialFn = (data: any) => {
    const { content, id } = data;
    welcomeFriendId.value = id;
    // 复用已有欢迎语（群聊欢迎语）只替换里面的content，不在覆盖素材内容
    const defaultData = selectMaterials.value.filter(item => item.is_default_del === 1);
    const arr = [...defaultData];
    arr.splice(props.maxNum);
    const res = initAlreadyMaterialData(arr);
    init(res, content);
};

const del = (index: number) => {
    selectMaterials.value.splice(index, 1);
    updateMaterials();
};

const getMaterlib = (res: any): void => {
    const arr: any[] = [];
    if (Array.isArray(res)) {
        res.forEach(item => item.data.length && arr.push(...formatMaterlis(item)));
        selectMaterials.value = filterOfficialAccountsData([...selectMaterials.value]);
    } else if (res?.local) {
        res.data.length && arr.push(...formatMaterlis(res));
    }
    selectMaterials.value.push(...arr);
    selectMaterials.value = selectMaterials.value.reduce((pre: any[], cur: any) => {
        if (!pre.some((item: any) => item.id && item.type === cur.type && item.id === cur.id)) {
            pre.push(cur);
        }
        return pre;
    }, []);
    selectMaterials.value.splice(props.maxNum);
    updateMaterials();
};

const filterOfficialAccountsData = (arr: any[]) => {
    return arr.filter(item => Number(item.type) === 10);
};

const formatMaterlis = (item: any): any[] => {
    const { type, data, local: local = false } = item;
    if (local) {
        return getLocalMaterlis(data, Number(type));
    } else {
        return getCommonMaterlis(data, Number(type));
    }
};

const getLocalMaterlis = (data: any, type: number) => {
    const local = true;
    switch (type) {
        case 1:
        case 2:
        case 4:
        case 5:
            return data.map((item: any) => {
                const { code, name, url } = item;
                let icon: string = hashTabs.value[type.toString()].icon;
                switch (type) {
                    case 5:
                        icon = getSuffixIcon(url) || hashTabs.value[type.toString()].icon;
                        break;
                }
                return {
                    type: type.toString(),
                    icon,
                    name,
                    imgUrl: url || item.imgUrl,
                    videoUrl: url,
                    code,
                    local,
                    url
                };
            });
        case 3:
            return data.map((item: any) => {
                const { code, title, cover_image_url, link_desc: link_decs, link_url } = item;
                const icon: string = hashTabs.value[type.toString()].icon;
                return {
                    type: type.toString(),
                    icon,
                    name: title || item.name,
                    linkUrl: cover_image_url || item.linkUrl,
                    code,
                    local,
                    link_title: title || item.name,
                    link_share_image: cover_image_url || item.linkUrl,
                    link_decs,
                    link_url
                };
            });
        default:
            return [];
    }
};

const getCommonMaterlis = (data: any, type: number) => {
    if (type === 10) {
        return mapOfficialAccountsData(data);
    } else {
        return mapDefaultData(data, type);
    }
};

const mapOfficialAccountsData = (data: any[]): any[] => {
    const list = [
        { name: '', type: 1, iconUrl: '/static/file/official.png' },
        { name: '', type: 2, iconUrl: '/static/file/text.png' },
        { name: '视频', type: 3, iconUrl: '/static/file/mov.png' },
        { name: '音频', type: 4, iconUrl: '/static/file/mp3.png' },
        { name: '图片', type: 5, iconUrl: '/static/file/pic.png' }
    ];
    return data.reduce((pre, cur) => {
        if (cur.articleType) {
            pre.push(cur);
        } else if (cur?.article_detail.length) {
            const arr = cur.article_detail.slice(0, props.maxNum).map(item => {
                const type = '10';
                const { type: articleType, id } = item;
                const name = list.find(el => el.type == articleType)?.name || item.title;
                const iconUrl = list.find(el => el.type == articleType)?.iconUrl || '';
                let icon = '';
                if (articleType === 1) {
                    icon = item.cover;
                } else {
                    icon = iconUrl;
                }
                return { type, name, icon, id, articleType };
            });
            pre.push(...arr);
        }
        return pre;
    }, []);
};

const mapDefaultData = (data: any[], type: number): any[] => {
    return data.map((item: any) => {
        let name: string = item[hashTabs.value[type.toString()].field] || item.name;
        let icon: string = hashTabs.value[type.toString()].icon || item.icon;
        const id: string | number = item.id;
        let imgUrl = '';
        let mpUrl = '';
        let videoUrl = '';
        let linkUrl = '';
        let appid = '';
        const defaultData: object = {};
        switch (type) {
            case 1:
                imgUrl = item.absolute_url || item.imgUrl;
                break;
            case 2:
                videoUrl = item.thumbnail_url || item.videoUrl;
                break;
            case 3:
                linkUrl = item.cover_image_url || item.linkUrl;
                if (item.is_default_del === 1) {
                    defaultData['is_default_del'] = item.is_default_del;
                    defaultData['linkUrl'] = item.linkUrl;
                    defaultData['link_decs'] = item.link_decs;
                    defaultData['link_share_image'] = item.link_share_image;
                    defaultData['link_title'] = item.link_title;
                }
                break;
            case 5:
                name = item.mediaFileInfo?.name || item.name;
                icon = getSuffixIcon(item.mediaFileInfo?.absolute_url || item.name) || item.icon;
                break;
            case 7:
                name = item.product_name || item.name;
                break;
            case 8:
                name = item.page_name || item.name;
                break;
            case 11:
                mpUrl = item.image_url || item.mpUrl;
                appid = item.appid;
                if (item.is_default_del === 1) {
                    defaultData['is_default_del'] = item.is_default_del;
                    defaultData['icon'] = item.icon;
                    defaultData['title'] = item.name;
                }
                break;
        }
        return {
            type: type.toString(),
            icon,
            name,
            id,
            imgUrl,
            mpUrl,
            videoUrl,
            linkUrl,
            appid,
            ...defaultData
        };
    });
};

const getOriginMaterialIds = (): number[] => {
    return selectMaterials.value.reduce((pre: any, next: any) => {
        if (originMaterialIds.value.includes(next.id)) {
            pre.push(next.id);
        }
        return pre;
    }, []);
};

const getNewMaterials = (): any[] => {
    return selectMaterials.value.reduce((pre: any, next: any) => {
        if (!originMaterialIds.value.includes(next.id)) {
            pre.push(next);
        }
        return pre;
    }, []);
};

const updateMaterials = (content?: string) => {
    const restIds = getOriginMaterialIds();
    const newMaterials = getNewMaterials();
    const params = {
        reKey: props.reKey,
        selectMaterials: [...selectMaterials.value],
        restIds,
        newMaterials,
        welcomeFriendId: welcomeFriendId.value
    };
    if (content) {
        params['content'] = content;
    }
    bus.emit('selectMaterials', params);
};

const init = (val: any[], content?: string) => {
    originMaterialIds.value.splice(0);
    originMaterialIds.value.push(...val.map(item => item.id));
    selectMaterials.value.splice(0);
    selectMaterials.value.push(...val);
    nextTick(() => {
        updateMaterials(content);
    });
};

const clearMaterial = () => {
    init([]);
};

watch(
    () => props.materialData,
    val => {
        const materials = selectMaterials.value.filter(item => !(item.is_default_del === 1));
        init([...val, ...materials]);
    },
    { immediate: true, deep: true }
);

onMounted(() => {
    getTabs();
});

defineExpose({
    clearMaterial,
    selectAlreadyMaterialShow,
    selectGroupAlreadyMaterialShow
});
</script>

<style lang="scss" scoped>
.materialContent {
    .material-content-list {
        margin: 10px 0;
        width: 100%;
        max-width: 430px;

        // min-height: 160px;
        .material-item {
            display: flex;
            align-items: center;
            justify-content: space-between;
            padding: 0 8px;
            height: 32px;
            line-height: 1;
            background-color: #f7f7f7;
            border-radius: 2px;
            margin-bottom: 6px;

            &:last-of-type {
                margin-bottom: 0;
            }

            .content {
                flex: 1;
                display: flex;
                align-items: center;

                img {
                    width: 22px;
                    height: 22px;
                }

                span {
                    flex: 1;
                    width: 0;
                    margin: 0 8px;
                    font-size: 12px;
                    line-height: 1;
                    color: #333;
                    white-space: nowrap;
                    text-overflow: ellipsis;
                    overflow: hidden;
                }
            }

            .el-icon {
                font-size: 16px;
                color: #ccc;

                &:hover {
                    cursor: pointer;
                    color: var(--el-text-color-placeholder);
                }
            }
        }
    }

    .material-content-com {
        .upload_btn {
            display: inline-block;
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
            margin-top: 8px;
            max-width: 100%;
            height: 32px;
            line-height: 32px;
            border-radius: 4px;
            border: 1px solid #d9d9d9;
            padding: 0 12px;
            box-sizing: border-box;
            font-size: 14px;
            font-family: STHeitiSC-Light, STHeitiSC;
            font-weight: 300;
            cursor: pointer;
            color: #969696;

            .el-icon {
                vertical-align: middle;
            }

            .upload_text {
                line-height: 32px;
                margin-left: 8px;
                white-space: nowrap;
            }
        }

        .disabled:hover {
            cursor: not-allowed;
        }
    }
}

.pop_select_box {
    .upload_pop {
        background: #fff;
        border-radius: 8px;
        display: flex;
        align-items: center;
        justify-content: space-between;
        width: auto;

        .item_pop {
            width: 44px;
            padding-top: 4px;
            display: flex;
            flex-direction: column;
            justify-content: center;
            align-items: center;
            border-radius: 4px;
            border: 1px solid #eee;
            margin-right: 8px;

            &:last-of-type {
                margin-right: 0;
            }

            &:hover {
                cursor: pointer;
                border-color: #f9a066;
            }

            .item_pop_icon {
                width: 30px;
                height: 30px;
            }

            .item_pop_name {
                font-size: 12px;
                margin-top: 2px;
                font-family: PingFangSC-Regular, 'PingFang SC';
                font-weight: 300;
                color: #555;
            }
        }
    }

    .upload_default_pop {
        text-align: center;
    }
}
</style>
